package Boke;
class Sock{
    //该方法实际上是对类对象(仅1个)加锁
    public synchronized static void fun1(){
        System.out.println("t1获得锁竞争(类对象加锁)：fun1()开始");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("t1释放锁，fun1()结束");
    }
    //与fun1()方法一样，也是对类对象加锁
    //只不过是代码书写不同
    public static void fun2(){
        synchronized (Sock.class){
            System.out.println("t2获得锁竞争(类对象加锁)：fun2()开始");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("t2释放锁，fun2()结束");
        }
    }
    //实际上是对实例化对象加锁(可有多个)
    public synchronized void fun3(){
        System.out.println("t1获得锁(实例对象加锁),fun3()");
        for (int i = 0; i < 50000; i++) {
            i++;
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("t1释放锁，fun3()结束");
    }
    //与fun4()方法一样，只不过代码书写不同罢了
    public void fun4() {
        synchronized (this){
            System.out.println("t2获得锁(实例对象加锁)，fun4()");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("t2释放锁，fun4()结束");
        }
    }
}
public class suo {
    public static void main(String[] args) throws InterruptedException {
        Sock sock=new Sock();
        Thread t1=new Thread(()->{
            //Sock.fun1();
            System.out.println("t1 开始");
            sock.fun3();
            System.out.println("t1 结束");
        });


        Thread t2=new Thread(()->{

            //Sock.fun2();
            System.out.println("t2 开始");
            sock.fun4();
            System.out.println("t2 结束");
        });
        t1.start();
        t2.start();

        t1.join();
        t2.join();
    }
}
